package Day_0218.CommomAPI;

import java.lang.reflect.Field;

/**
 * @author zxc
 * @date 2023/02/18 22:15
 **/
public class String_Unchanged {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        /**
         * String类型，不可变特点的原理
         * ===》
         * 简单来说，就是String类，其底层的数据结构是使用了（final关键字修饰的char类型数组）来存储字符，
         * 源码如下：
         * // The value is used for character storage.
         * private final char value[];
         *
         */

        /**
         * String类型真的是不可变的吗？
         * ===》
         * 1.String不可变，但不代表引用不可以变
         * ===》
         * （1）即，对于原先字符串String1 进行修改之后，使得当前的字符串变量str指向 新的字符串String2;
         *  即，字符串变量str所指向字符串的内存地址发生了变化;
         * （2）解析 ：
         *  实际上，原来String的内容是不变的，只是str由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址而已，
         *  也就是说多开辟了一块内存区域给"Hello World"字符串。
         *
         * 2.通过反射机制，去修改所谓的“不可变”String对象
         * ===》
         * 解析 ：
         * 用反射可以访问私有成员， 然后反射出String对象中的value属性， 进而改变通过获得的value引用改变数组的结构。
         *
         */

        // 创建字符串"Hello World"， 并赋给引用s
        String s = "Hello World";
        System.out.println("s = " + s); // Hello World
        // 获取String类中的value字段
        Field valueFieldOfString = String.class.getDeclaredField("value");
        // 改变value属性的访问权限
        valueFieldOfString.setAccessible(true);
        // 获取s对象上的value属性的值
        char[] value = (char[]) valueFieldOfString.get(s);
        // 改变value所引用的数组中的第5个字符
        value[5] = '_';
        System.out.println("s = " + s); // Hello_World


        /**
         * String str="i"与 String str=new String(“i”)一样吗？
         * ===》
         * 因为内存的分配方式不一样。
         * （1）String str="i"的方式，JVM 会将其分配到常量池中；
         * （2）String str=new String(“i”) ，则会被 JVM 分到堆内存中。
         *
         */

        /**
         * String s = new String(“xyz”);创建了几个字符串对象
         * ===》
         * 分类讨论：
         * （1）若是字符串常量池中不存在"xyz"的话，则是
         *  两个对象，一个是字符串常量池的"xyz"，一个是用new创建在堆上的对象;
         * （2）若是字符串常量池中存在"xyz"的话，则是
         *  一个对象，即使用new关键字，在堆上面所创建出来的String对象;
         *
         */
    }
}
